package com.econ.powercloud.ems.service.biz;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.econ.powercloud.clickhouse.entity.EmsFaultData;
import com.econ.powercloud.clickhouse.entity.EmsStatisticalDay;
import com.econ.powercloud.clickhouse.entity.EmsStatisticalMonth;
import com.econ.powercloud.clickhouse.entity.EmsStatisticalYear;
import com.econ.powercloud.common.base.facade.util.JacksonUtil;
import com.econ.powercloud.common.base.facade.util.TimeUtil;
import com.econ.powercloud.ems.dal.entity.EmsFault;
import com.econ.powercloud.ems.pojo.requestVO.EmsFaultRequestVO;
import com.econ.powercloud.ems.pojo.requestVO.ReportRequestVO;
import com.econ.powercloud.ems.service.dao.clickhouse.EmsFaultDataDAO;
import com.econ.powercloud.ems.service.dao.clickhouse.EmsStatisticalDayDAO;
import com.econ.powercloud.ems.service.dao.clickhouse.EmsStatisticalMonthDAO;
import com.econ.powercloud.ems.service.dao.clickhouse.EmsStatisticalYearDAO;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @ Description:
 * @ Author：hgp
 * @ Create:2022-10-18-9:20
 */
@Service
@Slf4j
public class ClickHouseBizService {
    @Autowired
    private EmsFaultDataDAO emsFaultDataDAO;
    @Autowired
    private EmsStatisticalYearDAO emsStatisticalYearDAO;
    @Autowired
    private EmsStatisticalMonthDAO emsStatisticalMonthDAO;
    @Autowired
    private EmsStatisticalDayDAO emsStatisticalDayDAO;

    private final static int MAX_SAVE_COUNTS = 5000;

    public List<EmsStatisticalMonth> selectDeviceDatasByTimes(Long startMonthTime, Long startDayTime, String reportId){
        return emsStatisticalMonthDAO.selectByCondition(startMonthTime,startDayTime,reportId);
    }

    public List<EmsStatisticalMonth> selectMonthListByCondition(Long startMonthTime, Long startDayTime, String reportId){
        return emsStatisticalMonthDAO.selectListByStartTimeAndEndTimeAndReportId(startMonthTime,startDayTime,reportId);
    }

    public List<EmsStatisticalDay> getDayDataByTimeAndReportId(Long time, String reportId){
        return emsStatisticalDayDAO.selectByTimeAndReportId(time, reportId);
    }

    public void deleteDayDataByTime(Long time, String reportId){
        emsStatisticalDayDAO.deleteByReportIdAndTime(reportId, time);
    }

    public void deleteMonthDataByTime(Long time, String reportId){
        emsStatisticalMonthDAO.deleteByReportIdAndTime(reportId, time);
        log.info("删除月报数据, time:{}, reportId:{}", time, reportId);
    }

    public void deleteYearDataByTime(Long time, String reportId){
        emsStatisticalYearDAO.deleteByReportIdAndTime(reportId, time);
    }

    /**
     * 根据requestVO获取日报列表
     * @param requestVO
     * @return
     */
    public List<EmsStatisticalDay> getBmuDayDataByCondition(ReportRequestVO requestVO){
        return emsStatisticalDayDAO.selectByCondition(requestVO);
    }

    /**
     * 根据requestVO获取月报列表
     * @param requestVO
     * @return
     */
    public List<EmsStatisticalYear> getYearDataByCondition(ReportRequestVO requestVO){
        return emsStatisticalYearDAO.selectByCondition(requestVO);
    }

    /**
     * 根据requestVO获取月报列表
     * @param requestVO
     * @return
     */
    public List<EmsStatisticalMonth> getMonthDataByCondition(ReportRequestVO requestVO){
        return emsStatisticalMonthDAO.selectByCondition(requestVO);
    }

    /**
     * 根据requestVO获取日报列表
     * @param requestVO
     * @return
     */
    public List<EmsStatisticalDay> getDayDataByCondition(ReportRequestVO requestVO){
        return emsStatisticalDayDAO.selectByCondition(requestVO);
    }

    /**
     * 将bmu每日数据存入ClickHouse月表
     * @param valueList
     */
    public void bmuStatisticalDayListDataIntoClickHouse(List<EmsStatisticalDay> valueList) {
        if (CollectionUtils.isEmpty(valueList)) {
            return ;
        }
        for (int i = 0; i < valueList.size(); i = i + MAX_SAVE_COUNTS) {
            int j = i + MAX_SAVE_COUNTS;
            if (j >= valueList.size()) {
                j = valueList.size();
            }
            List<EmsStatisticalDay> subList = valueList.subList(i, j);
            emsStatisticalDayDAO.insertBatch(Lists.newArrayList(subList));
            log.info("bmu每日数据插入ClickHouse, 插入数量:{}", subList.size());
        }
    }
    /**
     * 将年报数据存入ClickHouse年表
     * @param valueList
     */
    public void emsStatisticalYearListDataIntoClickHouse(List<EmsStatisticalYear> valueList) {
        if (CollectionUtils.isEmpty(valueList)) {
            return ;
        }
        for (int i = 0; i < valueList.size(); i = i + MAX_SAVE_COUNTS) {
            int j = i + MAX_SAVE_COUNTS;
            if (j >= valueList.size()) {
                j = valueList.size();
            }
            List<EmsStatisticalYear> subList = valueList.subList(i, j);
            emsStatisticalYearDAO.insertBatch(Lists.newArrayList(subList));
            log.info("年报数据插入ClickHouse, 插入数量: {}", subList.size());
        }
    }


    /**
     * 将月报数据存入ClickHouse年表
     * @param valueList
     */
    public void emsStatisticalMonthListDataIntoClickHouse(List<EmsStatisticalMonth> valueList) {
        if (CollectionUtils.isEmpty(valueList)) {
            return;
        }
        for (int i = 0; i < valueList.size(); i = i + MAX_SAVE_COUNTS) {
            int j = i + MAX_SAVE_COUNTS;
            if (j >= valueList.size()) {
                j = valueList.size();
            }
            List<EmsStatisticalMonth> subList = valueList.subList(i, j);
            emsStatisticalMonthDAO.insertBatch(Lists.newArrayList(subList));
            log.info("月报数据插入ClickHouse, 插入数量:{}", subList.size());
        }
    }

    /**
     * 将日报数据存入ClickHouse存入年表
     * @param valueList
     */
    public void emsStatisticalDayListDataIntoClickHouse(List<EmsStatisticalDay> valueList) {
        if (CollectionUtils.isEmpty(valueList)) {
            return;
        }
        for (int i = 0; i < valueList.size(); i = i + MAX_SAVE_COUNTS) {
            int j = i + MAX_SAVE_COUNTS;
            if (j >= valueList.size()) {
                j = valueList.size();
            }
            List<EmsStatisticalDay> subList = valueList.subList(i, j);
            emsStatisticalDayDAO.insertBatch(Lists.newArrayList(subList));
            log.info("日报数据插入ClickHouse, 插入数量:{}", subList.size());
        }
    }

    //--------------------------------------------------- 故障告警相关 -------------------------------------------------------------------------

    public Page<EmsFaultData> findListByCondition(EmsFaultRequestVO requestVO, List<String> energyStationIdList, int pageNo, int pageSize) {
        return emsFaultDataDAO.selectPageByCondition(requestVO, energyStationIdList, pageNo, pageSize);
    }

    public List<EmsFaultData> findListByTime(EmsFaultRequestVO requestVO) {
        return emsFaultDataDAO.selectListByTime(requestVO);
    }

    public EmsFault selectOneByFaultPidAndFaultResource(String faultPid, Integer faultResource){
        EmsFaultData emsFaultData = emsFaultDataDAO.selectOneByFaultPidAndFaultResource(faultPid, faultResource);
        return emsFaultData != null ? JacksonUtil.convertToObj(emsFaultData, EmsFault.class) : null;
    }

    public void updateEmsFaultById(EmsFaultData data) {
        EmsFaultData byId = emsFaultDataDAO.getById(data.getId());
        if (byId == null) {
            emsFaultDataDAO.insertOne(data);
        } else {
            emsFaultDataDAO.updateAllById(data);
        }
    }

    /**
     * 根据id查找故障告警
     *
     * @param id
     * @return
     */
    public EmsFaultData findEmsFaultById(String id) {
        EmsFaultData emsFaultData = emsFaultDataDAO.getById(id);
        return emsFaultData;
    }

    /**
     * 根据id查找故障告警
     *
     * @param ids
     * @return
     */
    public List<EmsFaultData> findEmsFaultByIds(List<String> ids) {
        List<EmsFaultData> emsFaultData = emsFaultDataDAO.listByIds(ids);
        return emsFaultData;
    }

    /**
     * 将故障告警数据存入ClickHouse
     *
     * @param valueList
     */
    public void emsFaultListDataIntoClickHouse(List<EmsFault> valueList) {
        if (CollectionUtils.isEmpty(valueList)) {
            return;
        }
        for (int i = 0; i < valueList.size(); i = i + MAX_SAVE_COUNTS) {
            int j = i + MAX_SAVE_COUNTS;
            if (j >= valueList.size()) {
                j = valueList.size();
            }
            List<EmsFault> subList = valueList.subList(i, j);
            List<EmsFaultData> emsFaultDataList = JacksonUtil.convertToList(Lists.newArrayList(subList), EmsFaultData.class);
            emsFaultDataList.stream().forEach(d->d.setId(
                    TimeUtil.format2String(d.getGmtCreate() == null ? System.currentTimeMillis() : d.getGmtCreate()
                            , DateTimeFormatter.ofPattern("yyyy")) + d.getId()));
            insertEmsFaultListData2ClickHouse(emsFaultDataList);
        }
    }

    /**
     * 将故障告警数据存入ClickHouse
     *
     * @param emsFault
     */
    public void emsFaultDataIntoClickHouse(EmsFault emsFault) {
        if (emsFault == null) {
            return;
        }
        EmsFaultData emsFaultData = JacksonUtil.convertToObj(emsFault, EmsFaultData.class);
        insertEmsFaultData2ClickHouse(emsFaultData);
    }

    /**
     * @description: 将故障告警列表数据存到ClickHouse具体实现
     */
    public void insertEmsFaultListData2ClickHouse(List<EmsFaultData> valueList) {
        if(CollectionUtils.isEmpty(valueList)) {
            return;
        }
        emsFaultDataDAO.insertBatch(valueList);
        log.info("故障告警数据插入Clickhouse, 插入数量: {}", valueList.size());
    }

    /**
     * @description: 将单个故障告警数据存到ClickHouse具体实现
     */
    private void insertEmsFaultData2ClickHouse(EmsFaultData data) {
        List<EmsFaultData> list = Lists.newArrayList(data);
        emsFaultDataDAO.insertBatch(list);
        log.info("单个故障告警数据插入Clickhouse, 插入数量: {}", list.size());
    }

    public List<EmsFaultData> findFaultListByPid(List<String> faultPids,Integer faultResource) {
        return emsFaultDataDAO.listByPid(faultPids,faultResource);
    }

    /**
     * 批量处理故障
     * @param dealState
     * @param operatorId
     * @param gmtModify
     * @param startTime
     * @param endTime
     */
    public void updateDealStateAndGmtModifyOperatorId(Integer dealState, String operatorId, Long gmtModify, Long startTime, Long endTime) {
        emsFaultDataDAO.updateDealStateAndGmtModifyOperatorId(dealState, operatorId, gmtModify, startTime, endTime);
    }
}
